/*
 * Clase con metodos abstractos que son necesarios durante la inereacción con la
 * base de datos
 */
package persistence;

import java.sql.*;
import encryption.Encrypter;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/**
 * @author edwin Xico
 * @version 1.0
 */
public class UsoPersisteceMySQLConnection {
    private static String user = "store_xico";
    private static String password = "store4xico";
    private static String dataBase = "store_product_registration";
    private static String host = "localhost";
    private static String sSQL = null;
    private static PersistenceMySQLConnection mysql = new PersistenceMySQLConnection(host, user, password,
            dataBase);
    private static boolean estado;
    
    //Objeto que encriptara las contraseñas
    private static Encrypter encrypter = new Encrypter();
    
    //Creando el modelo de tabla.
    private static DefaultTableModel DTM_Tabla;
    
    //String con el mensaje a mostrar...
    private static String message; 
    
    /**
     * Metodo que verifica si ya existe almenos un usuario en la base de datos.
     * @return
     */
    public static boolean hayUsuario(){
        mysql.connect();
        boolean toReturn = false;
        String stSQL = "SELECT ID_usuario, Usuario, Contrasena FROM usuarios WHERE CONCAT(ID_usuario, ' ', Usuario) like '% %'";
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);
            ResultSet rs = pStatement.executeQuery(stSQL);
            if(rs.next()){
                toReturn = true;
            }
            else {
                toReturn = false;
            }
            estado = true;
        }catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
        return toReturn;
    }
    
    public static boolean getEstado(){
        return estado;
    }
    
        /**
     * Metodo que se utiliza para verificar si el usuario y contraseña ingresados son válidos
     * @param usuarioX : el valor de usuario que se comparará con el de la base de datos
     * @param contrasenaX : el valor de la contrasena que se comparara con la de la base de datos
     * @return
     */
    public static boolean verificarUsuario(String usuarioX, String contrasenaX){
        mysql.connect();
        boolean toReturn = false;
        String stSQL = "SELECT Usuario, Contrasena FROM usuarios "
                + "WHERE CONCAT(Usuario, ' ', Contrasena) like '% %'";
        String usuario = "", contrasena = "";
        try {
           PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);
           ResultSet rs = pStatement.executeQuery(stSQL);
           while(rs.next()){
               usuario = encrypter.desencriptar(rs.getString("Usuario"));
               
               contrasena = encrypter.desencriptar(rs.getString("Contrasena"));
               if ((usuario.compareTo(usuarioX) == 0) && (contrasena.compareTo(contrasenaX) == 0)){
               toReturn = true;
               break;
               }
               else {
               toReturn = false;
               }
           }
        }catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
        return toReturn;
    }

        
    /**
     * Metodo quer realiza el proceso de conección con la base de datos y guardad0
     * de los datos
     * @param stSQL : Statemente SQL, es la instrucción que se desea realizar.
     * @param tFields : los datos con los que resalizará la instrucción.
     */
    public static void guardarEnBaseDatos(String stSQL, ArrayList<String> tFields){
        mysql.connect();
        message = "Los datos se han Ingresado de forma exitosa";
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);
            for(int x=0; x < tFields.size(); x++){
                pStatement.setString((x+1),tFields.get(x));
            }
            int cantElementos = pStatement.executeUpdate();
            if (cantElementos > 0) {
                JOptionPane.showMessageDialog(null, message);
            }
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
    }
    
    public static void agregarUsuario(ArrayList<String> tFields){
        sSQL = "INSERT INTO usuarios(Usuario, Contrasena) VALUES(?, ?)";
        guardarEnBaseDatos(sSQL, tFields);
    }
    
     /**
     * Metodo utilizado para agregar un Proveedor.
     * @param tFields : Arreglo de datos del proveedor que se desea
     * agregar.
     */
    public static void agregarProveedor(ArrayList<String> tFields) {
        sSQL = "INSERT INTO proveedores(Nombre, Detalle) VALUES(?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
    /**
     * Metodo utilizado para agregar una Marca.
     * @param tFields : Arreglo de datos de la marca que se desea agregar.
     */
    public static void agregarMarca(ArrayList<String> tFields) {
        sSQL = "INSERT INTO marcas(Nombre, Detalle) VALUES(?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
    /**
     * Metodo utilizado para agregar un registro.
     * @param tFields : Arreglo de datos del registro que se desea agregar.
     */
    public static void agregarRegistros(ArrayList<String> tFields) {
        sSQL = "INSERT INTO registros(ID_usuario, Detalle) VALUES(?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
    
    /**
     * Metodo utilizado para agregar el precio de algún producto
     * @param tFields : Arreglo de datos del objeto que se desea
     * agregar.
     */
    public static void agregarPreciosProducto(ArrayList<String> tFields) {
        sSQL = "INSERT INTO precios_producto(ID_proveedor, Precio_paquete, Cant_por_paquete, Precio_compra, "
                + "Precio_sugerido_venta, Precio_venta) VALUES(?,?,?,?,?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
    /**
     * Metodo utilizado para agregar algun producto de libreria.
     * @param tFields : Arreglo de datos del producto que se desea
     * agregar.
     */
    public static void agregarProductosLibreria(ArrayList<String> tFields) {
        sSQL = "INSERT INTO productos_libreria(Codigo, Nombre, "
                + "ID_Marca, ID_precios_producto) VALUES(?,?,?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
    /**
     * Metodo utilizado para agregar un producto de tienda.
     * @param tFields : Arreglo de datos del producto que se desea
     * agregar.
     */
    public static void agregarProductosTienda(ArrayList<String> tFields) {
        sSQL = "INSERT INTO productos_tienda(Codigo, Nombre, "
                + "ID_Marca, ID_precios_producto) VALUES(?,?,?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
        /**
     * Metodo utilizado para agregar un producto de tienda.
     * @param tFields : Arreglo de datos del producto que se desea
     * agregar.
     */
    public static void agregarProductosVarios(ArrayList<String> tFields) {
        sSQL = "INSERT INTO productos_varios(Codigo, Nombre, "
                + "ID_Marca, ID_precios_producto) VALUES(?,?,?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    
    /**
     * Metodo para encontrar un dato específico dentro de la tabla proveedor
     * @param columnX columna en la que se buscará
     * @param filtroX el dato que se buscara dentro de la columna
     * @return 
     */
    public static String encontrarIDProveedor(String filtroX){
        String toReturn = new String();
        String[] titulos = {"ID_proveedor", "Nombre", "Detalle"};
        sSQL = "SELECT ID_proveedor, Nombre FROM proveedores" +
                " WHERE Nombre like '%"+filtroX+"%'";
        if(filtroX.equals("")){
  
        }
        else if(!filtroX.equals("")){
            toReturn = getID(sSQL,titulos);
        }     
        return toReturn;
    }
    
    /**
     * Metodo para encontrar un dato específico dentro de la tabla marcas
     * @param columnX columna en la que se buscará
     * @param filtroX el dato que se buscara dentro de la columna
     * @return 
     */
    public static String encontrarIDMarca(String filtroX){
        String toReturn = new String();
        String[] titulos = {"ID_marca", "Nombre",};
        sSQL = "SELECT ID_marca, Nombre FROM marcas WHERE Nombre like '%"+filtroX+"%'";
        if(filtroX.equals("")){
  
        }
        else if(!filtroX.equals("")){
            toReturn = getID(sSQL,titulos);
        }     
        return toReturn;
    }
    
    public static String getCantidadDatos(String tableX){
        String toReturn = "";
        String[] titulosX = {"COUNT( * )"};
        sSQL = "SELECT COUNT( * ) FROM " + tableX;
        toReturn = getCantidadDatos(sSQL, titulosX);
        return toReturn;
        
    }
    
    public static String[] encontrarNombresMarcas(){
        String[] toReturn;
        String[] titulos = {"ID_marca", "Nombre", "Detalle"};
        sSQL = "SELECT Nombre FROM marcas";
        toReturn = parseArrayString(getNombres(sSQL,titulos));
        return toReturn;
    }
    
    public static String[] encontrarNombresProveedor(){
        String[] toReturn;
        String[] titulos = {"ID_proveedor", "Nombre", "Detalle"};
        sSQL = "SELECT Nombre FROM proveedores";
        toReturn = parseArrayString(getNombres(sSQL,titulos));
        return toReturn;
    }
    
    
    private static String[] parseArrayString(ArrayList<String> x1){
        String[] toReturn;
        toReturn = new String[x1.size()];
        for(int x = 0; x< x1.size(); x++){
            toReturn[x] = x1.get(x);
        }
        return toReturn;
    }
        
    /**
     * Metodo tulizado para cargar el ID de las tablas
     * @param stSQL : la sentencia SQL que se ejecutara
     * @param titulosX : los titulos de las columnas de la tabla
     */
    public static String getID(String stSQL, String[] titulosX){
        mysql.connect();
        String IDX = new String();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            if(rs.next()){
                IDX = rs.getString(titulosX[0]);                 
            }
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }        
       return IDX;
    }
    
        public static String getCantidadDatos(String stSQL, String[] titulosX){
        mysql.connect();
        String IDX = new String();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            if(rs.next()){
                IDX = rs.getString(titulosX[0]);                 
            }
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }        
       return IDX;
    }
    
        
    public static void cargarTabla(String txtABuscar){
        
    }
    
    public static void cargarTablaBebidas(JTable X, String filtroX){
        String[] titulos = {"ID","Nombre","Marca","Proveedor", "Precio de Comra",
            "Precio por paquete", "Cantidad por paquete", "Precio Sug. de Venta", "Precio de Venta"};
        String[] titulosBD = {"ID_bebida", "Nombre", "marcas.Nombre", "proveedores.Nombre",
            "Precio_paquete", "Cant_por_paquete", "Precio_compra" , "Precio_sugerido_venta", "Precio_venta"};
        String[] registro = new String[9];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT  `bebidas`.`Nombre` ,  `bebidas`.`ID_bebida` ,  `precios_producto`.`Precio_paquete`,`precios_producto`.`Cant_por_paquete`, `precios_producto`.`Precio_compra` ,  `precios_producto`.`Precio_sugerido_venta` , `proveedores`.`Nombre` ,  `marcas`.`Nombre` ,  `precios_producto`.`Precio_venta` " +
        "FROM bebidas "+
        "LEFT JOIN  `store_product_registration`.`marcas` ON  `bebidas`.`ID_marca` =  `marcas`.`ID_marca` "+
        "LEFT JOIN  `store_product_registration`.`precios_producto` ON  `bebidas`.`ID_precios_producto` =  `precios_producto`.`ID_precios_producto` "+
        "LEFT JOIN  `store_product_registration`.`proveedores` ON  `precios_producto`.`ID_proveedor` =  `proveedores`.`ID_proveedor`";

        if(filtroX.equals("")){
            cargarTablasSQL(X, sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(X, filtroX, sSQL, titulosBD, registro);
        }       
    }
    
    public static void cargarTablaTienda(JTable X, String filtroX){
        String[] titulos = {"ID","Nombre","Marca","Proveedor", "Precio de Comra",
            "Precio por paquete", "Cantidad por paquete", "Precio Sug. de Venta", "Precio de Venta"};
        String[] titulosBD = {"ID_productos_tienda", "Nombre", "marcas.Nombre", "proveedores.Nombre",
            "Precio_paquete", "Cant_por_paquete", "Precio_compra" , "Precio_sugerido_venta", "Precio_venta"};
        String[] registro = new String[9];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT  `productos_tienda`.`Nombre` ,  `productos_tienda`.`ID_productos_tienda` ,  `precios_producto`.`Precio_paquete`,`precios_producto`.`Cant_por_paquete`, `precios_producto`.`Precio_compra` ,  `precios_producto`.`Precio_sugerido_venta` , `proveedores`.`Nombre` ,  `marcas`.`Nombre` ,  `precios_producto`.`Precio_venta` " +
        "FROM productos_tienda "+
        "LEFT JOIN  `store_product_registration`.`marcas` ON  `productos_tienda`.`ID_marca` =  `marcas`.`ID_marca` "+
        "LEFT JOIN  `store_product_registration`.`precios_producto` ON  `productos_tienda`.`ID_precios_producto` =  `precios_producto`.`ID_precios_producto` "+
        "LEFT JOIN  `store_product_registration`.`proveedores` ON  `precios_producto`.`ID_proveedor` =  `proveedores`.`ID_proveedor`";

        if(filtroX.equals("")){
            cargarTablasSQL(X, sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(X, filtroX, sSQL, titulosBD, registro);
        }       
    }
    

    public static void cargarTablaLibreria(JTable X, String filtroX){
        String[] titulos = {"ID","Nombre","Marca","Proveedor", "Precio por paquete", "cantidad por paquete", "Precio de Comra", "Precio Sug. de Venta", "Precio de Venta"};
        String[] titulosBD = {"ID_productos_libreria","Nombre","marcas.Nombre","proveedores.Nombre", "precios_producto.Precio_paquete", "Cant_por_paquete", "Precio_compra" , "Precio_sugerido_venta", "Precio_venta"};
        String[] registro = new String[9];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT  `productos_libreria`.`Nombre` ,  `productos_libreria`.`ID_productos_libreria` ,  `precios_producto`.`Precio_paquete` , `precios_producto`.`Cant_por_paquete` ,`precios_producto`.`Precio_compra` ,  `precios_producto`.`Precio_sugerido_venta` , `proveedores`.`Nombre` ,  `marcas`.`Nombre` ,  `precios_producto`.`Precio_venta` " +
"FROM productos_libreria "+
"LEFT JOIN  `store_product_registration`.`marcas` ON  `productos_libreria`.`ID_marca` =  `marcas`.`ID_marca` "+
"LEFT JOIN  `store_product_registration`.`precios_producto` ON  `productos_libreria`.`ID_precios_producto` =  `precios_producto`.`ID_precios_producto` "+
"LEFT JOIN  `store_product_registration`.`proveedores` ON  `precios_producto`.`ID_proveedor` =  `proveedores`.`ID_proveedor`";
                
        if(filtroX.equals("")){
            cargarTablasSQL(X, sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(X, filtroX, sSQL, titulosBD, registro);
        }       
    }
    
    
    public static void cargarTablaVarios(JTable X, String filtroX){
            String[] titulos = {"ID","Nombre","Marca","Proveedor", "Precio de Comra", "Precio Sug. de Venta", "Precio de Venta"};
            String[] titulosBD = {"ID_productos_varios","Nombre","marcas.Nombre","proveedores.Nombre", "Precio_compra" , "Precio_sugerido_venta", "Precio_venta"};
            String[] registro = new String[7];
            DTM_Tabla = new DefaultTableModel(null, titulos);
            sSQL = "SELECT  `productos_varios`.`Nombre` ,  `productos_varios`.`ID_productos_varios` ,  `precios_producto`.`Precio_compra` ,  `precios_producto`.`Precio_sugerido_venta` , `proveedores`.`Nombre` ,  `marcas`.`Nombre` ,  `precios_producto`.`Precio_venta` " +
            "FROM productos_varios "+
            "LEFT JOIN  `store_product_registration`.`marcas` ON  `productos_varios`.`ID_marca` =  `marcas`.`ID_marca` "+
            "LEFT JOIN  `store_product_registration`.`precios_producto` ON  `productos_varios`.`ID_precios_producto` =  `precios_producto`.`ID_precios_producto` "+
            "LEFT JOIN  `store_product_registration`.`proveedores` ON  `precios_producto`.`ID_proveedor` =  `proveedores`.`ID_proveedor`";

            if(filtroX.equals("")){
                cargarTablasSQL(X, sSQL, titulosBD, registro);
            }
            else if(!filtroX.equals("")){
                busquedaTablasSQL(X, filtroX, sSQL, titulosBD, registro);
            }       
    }
    
    
    public static void cargarTablaMarcas(JTable X, String filtroX){
            String[] titulos = {"ID","Nombre","Detalle"};
            String[] titulosBD = {"ID_marca","marcas.Nombre","marcas.Detalle"};
            String[] registro = new String[3];
            DTM_Tabla = new DefaultTableModel(null, titulos);
            sSQL = "SELECT  `marcas`.`ID_marca`, `marcas`.`Nombre` ,  `marcas`.`Detalle` " +
            "FROM marcas ";

            if(filtroX.equals("")){
                cargarTablasSQL(X, sSQL, titulosBD, registro);
            }
            else if(!filtroX.equals("")){
                busquedaTablasSQL(X, filtroX, sSQL, titulosBD, registro);
            }       
    }
    
    public static void cargarTablaProveedores(JTable X, String filtroX){
            String[] titulos = {"ID","Nombre","Detalle"};
            String[] titulosBD = {"ID_proveedor","Nombre","Detalle"};
            String[] registro = new String[3];
            DTM_Tabla = new DefaultTableModel(null, titulos);
            sSQL = "SELECT  `proveedores`.`ID_proveedor`, `proveedores`.`Nombre` ,  `proveedores`.`Detalle` " +
            "FROM proveedores";

            if(filtroX.equals("")){
                cargarTablasSQL(X, sSQL, titulosBD, registro);
            }
            else if(!filtroX.equals("")){
                busquedaTablasSQL(X, filtroX, sSQL, titulosBD, registro);
            }       
    }
    
    
    /**
     * Metodo que realiza la busqueda en la base de datos.
     * @param filtroX : la palabra que se comparara para obtener los resultados
     * @param stSQL : la sentencia SQL que se ejecutará
     * @param titulosX : los titulos de los campos de una tabla.
     * @param registroX : el arrreglo en el que se guardaran temporalmente los datos.
     */
    public static void busquedaTablasSQL(JTable X, String filtroX, String stSQL, String[] titulosX,
            String[] registroX) {
        mysql.connect();
        ArrayList<String> misDatosLineas = new ArrayList<String>();
        ArrayList<ArrayList<String>> misDatos = new ArrayList<ArrayList<String>>();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            while(rs.next()){
                misDatosLineas.add(rs.getString(titulosX[0]));
                for(int x=1; x < titulosX.length; x++) {
                    misDatosLineas.add(rs.getString(titulosX[x]));                    
                }
                misDatos.add(new ArrayList<String>(misDatosLineas));
                while (!misDatosLineas.isEmpty()){
                    misDatosLineas.remove(0);                
                }
            }
            for(int x=0; x< misDatos.size();x++){
                for(int y=0; y< misDatos.get(x).size();y++){
                    if(misDatos.get(x).get(y).compareTo(filtroX) == 0){
                        for(int z=0; z < misDatos.get(x).size(); z++){
                            registroX[z] = misDatos.get(x).get(z);                        
                        }
                    }
                }
                DTM_Tabla.addRow(registroX);
            }            
            X.setModel(DTM_Tabla);            
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
    }
        
    /**
     * Metodo tulizado para cargar las tablas con todos su datos
     * @param stSQL : la sentencia SQL que se ejecutara
     * @param titulosX : los titulos de las columnas de la tabla
     * @param registroX : el arreglo en el que se guardaran temporalmente los datos de una fila
     */
    public static void cargarTablasSQL(JTable X, String stSQL, String[] titulosX,
            String[] registroX){
        mysql.connect();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            while(rs.next()){
                registroX[0] = rs.getString(titulosX[0]);
                for(int x=1; x < titulosX.length;x++){
                    registroX[x] = rs.getString(titulosX[x]);
                }                   
                DTM_Tabla.addRow(registroX);
            }
            X.setModel(DTM_Tabla);            
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }        
    }
    
    
    public static ArrayList<String> getNombres(String stSQL, String[] titulosX){
        mysql.connect();
        ArrayList<String> datosX = new ArrayList<String>();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            while(rs.next()){
                datosX.add(rs.getString(titulosX[1]));                 
            }
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }        
       return datosX;
    }
    

}
